package com.wxxymaker.edu.controller.view;

import com.blade.ioc.annotation.Inject;
import com.blade.mvc.RouteContext;
import com.blade.mvc.annotation.GetRoute;
import com.blade.mvc.annotation.Param;
import com.blade.mvc.annotation.Path;
import com.blade.mvc.annotation.PathParam;
import com.blade.mvc.http.Request;
import com.blade.mvc.http.Response;
import com.wxxymaker.edu.model.entity.Comment;
import com.wxxymaker.edu.model.entity.Material;
import com.wxxymaker.edu.model.entity.User;
import com.wxxymaker.edu.roles.CourseLearnRoles;
import com.wxxymaker.edu.roles.IgnoreAuth;
import com.wxxymaker.edu.roles.StudentRoles;
import com.wxxymaker.edu.service.*;
import com.wxxymaker.edu.utils.HttpUtil;
import com.wxxymaker.edu.utils.TokenUtils;
import io.github.biezhi.anima.page.Page;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author: soft
 * @Date: 2018/7/28 15:04
 * @Desc: 课程相关页面控制器
 */
@Path("/course")
@StudentRoles
@Slf4j
public class CourseViewHandler {

    @Inject
    private LearnCourseService learnCourseService;
    @Inject
    private CourseService courseService;
    @Inject
    private CourseCollectService courseCollectService;

    @Inject
    private MaterialService materialService;

    @Inject
    private CommentService commentService;

    /**
     * 课程信息页
     * @param kid 课程id
     */
    @IgnoreAuth
    @GetRoute("/:kid/info")
    public String info(RouteContext ctx,
                       @PathParam Integer kid) {
        // 在判断这个kid是不是被当前登陆的用户加入学习
        boolean redirect  = this.isNeedRedirect();
        boolean join      = this.isJoin(kid);
        boolean myPublish = this.isMyPublish(kid);
        boolean collect   = this.isCollect(kid);
        if (redirect && (join || myPublish)) {
            ctx.redirect("/course/" + kid + "/join/info");
        } else {
            if (!HttpUtil.isAjax()) courseService.addViews(kid);
        }
        ctx.attribute("isMyPublish", myPublish); // 公告添加是否显示
        ctx.attribute("isJoin", join); // 动态改变加入学习按钮
        ctx.attribute("join_stu", false);
        ctx.attribute("isCollect", collect); // 判断课程是否被收藏
        ctx.attribute("wid", 0L); // 防止报错
        return render("info", false);
    }

    /**
     * 加入学习后的课程信息界面
     * 需要至少学生角色
     *
     * 如果是学生，则该课程必须是加入学习的，如果课程是该老师发布的则可以直接打开
     * @param kid 课程id
     * @param wid 问答id 如果存在就直接打开问答详情页
     */
    @CourseLearnRoles
    @GetRoute("/:kid/join/info")
    public String info_(RouteContext ctx,
                        @PathParam Integer kid,
                        @Param(defaultValue = "0") Long wid) {
        ctx.attribute("join_stu", true);
        ctx.attribute("wid", wid);
        boolean collect = this.isCollect(kid);
        boolean myPublish = this.isMyPublish(kid);
        ctx.attribute("isMyPublish", myPublish);
        ctx.attribute("isCollect", collect);
        return render("info", false);
    }

    /**
     * 课程简介
     */
    @IgnoreAuth
    @GetRoute("/:kid/intro")
    public String intro(Request request,
                       @PathParam String kid) {
        return render("intro");
    }

    /**
     * 课程目录
     */
    @IgnoreAuth
    @GetRoute("/:kid/tasks")
    public String tasks(RouteContext ctx,
                        @PathParam Integer kid) {
        if (this.isJoin(kid)) {
            ctx.attribute("isJoin", true); // 如果登录了,且加入了学习,则可以直接观看
        }
        return render("tasks");
    }

    /**
     * 课程评论
     */
    @IgnoreAuth
    @GetRoute("/:kid/comments")
    public String comments(Request request,
                           @PathParam Integer kid,
                           @Param(defaultValue = "1") Integer page,
                           @Param(defaultValue = "1") Integer size) {
        request.attribute("commented", false);
        User user = TokenUtils.currentUser();
        if (user != null) {
            Integer id = user.getId();
            Page<Comment> pages = commentService.pages(id, kid, page, size);
            if (pages !=null){
                request.attribute("commented", true);
            }
        }
        return render("comments");
    }

    /**
     * 课程笔记
     */
    @IgnoreAuth
    @GetRoute("/:kid/notes")
    public String notes(Request request,
                        @PathParam String kid) {

        return render("notes");
    }

/*##################################################*/

    /**
     * 资料区
     */
    @CourseLearnRoles
    @GetRoute("/:kid/material")
    public String material(Request request,
                        @PathParam String kid) {

        return render("material");
    }

    /**
     * 问答区
     */
    @CourseLearnRoles
    @GetRoute("/:kid/ask")
    public String ask(Request request,
                        @PathParam String kid) {

        return render("ask");
    }

    /**
     * 问答详情
     */
    @CourseLearnRoles
    @GetRoute("/:kid/ask/:wid/info")
    public String askInfo(Request request,
                          @PathParam String kid,
                          @PathParam String wid) {

        return render("askInfo");
    }

    /**
     * 练习区
     */
    @CourseLearnRoles
    @GetRoute("/:kid/practice")
    public String practice(Request request,
                      @PathParam String kid) {

        return render("practice");
    }

    /**
     * 课程任务播放区
     */
    @CourseLearnRoles
    @GetRoute("/:kid/task/:tid/show")
    public String show(Request request,
                       @PathParam String kid,
                       @PathParam String tid,
                       @Param(defaultValue = "1") Integer i) {
        request.attribute("tid", tid);
        return render("show/index", false);
    }

    /**
     * 视频播放
     * @param mid 资源id
     * @param pv 是否预览，当pv大于1时 允许直接预览
     */
    @CourseLearnRoles
    @GetRoute("/:kid/task/:tid/video")
    public void video_(Request request,
                       Response response,
                       @PathParam String kid,
                       @PathParam String tid,
                       @Param(name = "wid") Integer mid,
                       @Param(defaultValue = "0") Integer pv) {
        String text = "/course/" + kid + "/task/" + tid + "/show";
        if (!HttpUtil.hasReferer(text) && pv <= 0) {
            response.render(HttpUtil._404());
        }
        Material material = materialService.byId(mid);
        if (material == null) {
            response.redirect("/403");
        } else {
            request.attribute("material", material);
            request.attribute("tid", tid);
            response.render(render("show/video", false));
        }
    }

    /**
     * 根据是不是Ajax请求返回不一样的结果
     * @param view 视图
     * @param isAjax 是否ajax
     * @return 视图
     */
    private String render(String view, boolean isAjax) {
        if (!isAjax) {
            return "course/" + view;
        } else {
            if (HttpUtil.isAjax()) {
                return "course/" + view;
            }
            return HttpUtil._404();
        }
    }

    /**
     * 默认是ajax请求
     * @param view 视图
     * @return 视图
     */
    private String render(String view) {
        return this.render(view, true);
    }

    /**
     * 判断是否需要自动跳转到学习界面
     */
    private boolean isNeedRedirect() {
        // 判断是不是来自需要跳转的页面
        return HttpUtil.isFrom("/", "/index", "/allClass", "/search");
    }

    /**
     * 判断课程是不是被当前登录用户(如果登录)加入学习
     * @param kid 课程id
     * @return 是否
     */
    private boolean isJoin(int kid) {
        // 判断用户是否登录
        User user = TokenUtils.currentUser();
        if (null != user) {
            // 判断该课程是否被加入学习
            return learnCourseService.isJoin(kid, user.getId());
        }
        return false;
    }

    private boolean isCollect(Integer kid) {
        // 判断用户是否登录
        User user = TokenUtils.currentUser();
        if (user != null) {
            return courseCollectService.isCollect(user.getId(), kid);
        }
        return false;
    }

    /**
     * 判断是不是当前用户发布的
     * @param kid 课程id
     */
    private boolean isMyPublish(int kid) {
        try {
            return courseService.isMyPublish(kid, TokenUtils.currentUser().getId());
        } catch (Exception e) {
            log.error("异常(未登录?): " + e.getMessage());
            return false;
        }
    }
}
